﻿using WhaleAccount.Contracts.Services;
using WhaleAccount.Helpers;
using WhaleAccount.Models;

namespace WhaleAccount.Services;
public class RecordService : IRecordService
{
    private readonly DatabaseContext _dbContext;

    public RecordService()
    {
        _dbContext = DatabaseContext.GetDbContext();
    }

    async Task<IEnumerable<DayRecordSummary>> IRecordService.GetDayRecordSummaryListAsync(int year, int month)
    {
        var _dayRecordSummaryList = GetDayRecordSummaryList(year, month);

        await Task.CompletedTask;
        return _dayRecordSummaryList;
    }

    async Task<IEnumerable<MonthRecordSummary>> IRecordService.GetMonthRecordSummaryListAsync(int year)
    {
        var _monthRecordSummaryList = GetMonthRecordSummaryList(year);

        await Task.CompletedTask;
        return _monthRecordSummaryList;
    }

    async Task<IEnumerable<Record>> IRecordService.GetRecordListAsync(DateTime date)
    {
        var recordList = from r in _dbContext.Records
                         where r.Date.Year == date.Year
                            && r.Date.Month == date.Month
                            && r.Date.Day == date.Day
                         orderby r.Date descending
                         select r;

        await Task.CompletedTask;
        return recordList;
    }

    async Task<int> IRecordService.AddRecordAsync(Record record)
    {
        _dbContext.Records.Add(record);
        var count = _dbContext.SaveChanges();

        await Task.CompletedTask;
        return count;
    }

    async Task<int> IRecordService.UpdateRecordAsync(Record record)
    {
        _dbContext.Records.Update(record);
        var count = _dbContext.SaveChanges();

        await Task.CompletedTask;
        return count;
    }

    async Task<int> IRecordService.DeleteRecordsAsync(Record record)
    {
        _dbContext.Records.Remove(record);
        var count = _dbContext.SaveChanges();

        await Task.CompletedTask;
        return count;
    }

    private IEnumerable<DayRecordSummary> GetDayRecordSummaryList(int year, int month)
    {
        var keyValuePairs = new Dictionary<DateTime, DayRecordSummary>();
        var records = from r in _dbContext.Records
                      where r.Date.Year == year && r.Date.Month == month
                      orderby r.Date descending
                      select r;
        foreach (var record in records)
        {
            var date = new DateTime(record.Date.Year, record.Date.Month, record.Date.Day);
            if (keyValuePairs.ContainsKey(date))
            {
                var dayRecordSummary = keyValuePairs[date];
                if (record.Category == 1)
                {
                    dayRecordSummary.Income += record.Value;
                }
                else if (record.Category == 0)
                {
                    dayRecordSummary.Expense += record.Value;
                }
            }
            else
            {
                var value = new DayRecordSummary(date);
                if (record.Category == 1)
                {
                    value.Income = record.Value;
                }
                else if (record.Category == 0)
                {
                    value.Expense = record.Value;
                }
                keyValuePairs.Add(date, value);
            }

            keyValuePairs[date].Records.Add(record);
        }
        var dayRecordSummaries = keyValuePairs.Values;
        return dayRecordSummaries;
    }

    private IEnumerable<MonthRecordSummary> GetMonthRecordSummaryList(int year)
    {
        var records = _dbContext.Records.Where(r => r.Date.Year == year);
        var monthRecordDict = new Dictionary<int, List<Record>>();
        foreach (var record in records)
        {
            var month = record.Date.Month;
            if (monthRecordDict.ContainsKey(month))
            {
                monthRecordDict[month].Add(record);
            }
            else
            {
                monthRecordDict.Add(month, new List<Record>() { record });
            }
        }

        var monthRecordSummaryList = new List<MonthRecordSummary>();
        foreach (var monthRecord in monthRecordDict)
        {
            var date = new DateTime(year, monthRecord.Key, 1);
            var monthRecordSummary = new MonthRecordSummary(date, monthRecord.Value);
            monthRecordSummaryList.Add(monthRecordSummary);
        }

        return monthRecordSummaryList;
    }
}
